package com.abso.sunlight.explorer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;

import com.abso.sunlight.api.Legislator;
import com.abso.sunlight.explorer.viewers.ExplorerTreeNode;

/**
 * Miscellaneous selection utilities.
 */
public final class SelectionUtils {

    /** Private constructor (don't instantiate). */
    private SelectionUtils() {
    }

    /**
     * Returns the currently selected Explorer tree node, or <code>null</code> if the current selection is not valid.
     * 
     * @param sel
     *            the current selection.
     * @param forceSingleSelection
     *            if <code>true</code> the selection must be composed by a single element.
     * @return the currently selected Explorer tree node, or <code>null</code> if the selection does not satisfy the criteria.
     */
    public static final ExplorerTreeNode getSelectedExplorerTreeNode(ISelection sel, boolean forceSingleSelection) {
        Object selectedObj = getSelectedObject(sel, forceSingleSelection);
        if (selectedObj instanceof ExplorerTreeNode) {
            return (ExplorerTreeNode) selectedObj;
        } else {
            return null;
        }
    }

    /**
     * Returns the currently selected legislator, or <code>null</code> if the current selection is not valid.
     * 
     * @param sel
     *            the current selection.
     * @param forceSingleSelection
     *            if <code>true</code> the selection must be composed by a single element.
     * @return the currently selected legislator, or <code>null</code> if the selection does not satisfy the criteria.
     */
    public static final Legislator getSelectedLegislator(ISelection sel, boolean forceSingleSelection) {
        Object selectedObj = getSelectedObject(sel, forceSingleSelection);
        if (selectedObj instanceof Legislator) {
            return (Legislator) selectedObj;
        } else {
            return null;
        }
    }

    /**
     * Returns the currently selected object, or <code>null</code> if the current selection is not valid.
     * 
     * @param sel
     *            the current selection.
     * @param forceSingleSelection
     *            if <code>true</code> the selection must be composed by a single element.
     * @return the currently selected object, or <code>null</code> if the selection does not satisfy the criteria.
     */
    public static final Object getSelectedObject(ISelection sel, boolean forceSingleSelection) {
        if (sel instanceof IStructuredSelection) {
            IStructuredSelection ssel = (IStructuredSelection) sel;
            if (forceSingleSelection && (ssel.size() != 1)) {
                return null;
            }
            return ssel.getFirstElement();
        }
        return null;
    }

    /**
     * Returns the currently selected legislators.
     * 
     * @param sel
     *            the current selection.
     * @return the selected legislators, extracted from <i>sel</i>.
     */
    public static List<Legislator> getSelectedLegislators(ISelection sel) {
        if (sel instanceof IStructuredSelection) {
            IStructuredSelection ssel = (IStructuredSelection) sel;
            List<Legislator> legislators = new ArrayList<Legislator>(ssel.size());
            for (Iterator<?> i = ssel.iterator(); i.hasNext();) {
                Object obj = i.next();
                if (obj instanceof Legislator) {
                    legislators.add((Legislator) obj);
                }
            }
            return legislators;
        }
        return Collections.emptyList();
    }

}
